<?php
/*
Extension Name: PFC
Extension Url: http://code.google.com/p/vanilla-friends/
Description: Integrates phpFreeChat into Vanilla.
Version: 1.2.1
Author: squirrel
Author Url: http://digitalsquirrel.com/
*/


// !!! DO NOT make changes to this file !!!
// If you want to change the PFC settings, install SetList!

// Define permissions and dictionary entries.
$Context->SetDefinition('PFC.LogDeleted', 'The log file has been deleted.');
$Context->SetDefinition('PFC.ErrPermission', 'You do not have permission to use the chat room.');
$Context->SetDefinition('PFC.ErrLoadFailed', 'Could not load the chat client.');
$Context->SetDefinition('PERMISSION_USE_CHAT', 'Use chat room');
$Context->SetDefinition('PERMISSION_CHAT_ADMIN', 'Chat room administrator');
$Configuration['PERMISSION_USE_CHAT'] = '0';
$Configuration['PERMISSION_CHAT_ADMIN'] = '0';

// Define path to phpFreeChat.
$Configuration['PfcPath'] = 'PFC/phpfreechat-1.2/';
$Configuration['PfcUrl']  = $Context->Configuration['BASE_URL'] . 'extensions/' . $Context->Configuration['PfcPath'];
$Configuration['PfcPath'] = $Configuration['EXTENSIONS_PATH'] . $Configuration['PfcPath'];

// Config defaults.
$Context->Configuration['PfcPageTitle'] = ForceString(@$Context->Configuration['PfcPageTitle'], 'Chat Room');

// Define helper functions for the settings form.
if ( 'settings.php' == $Context->SelfUrl ) {

	$Configuration['PfcCache'] = $Configuration['PfcPath'] . 'data/private/cache/' . md5($Configuration['APPLICATION_PATH']) . '.php';
	$Configuration['PfcChat']  = $Configuration['PfcPath'] . 'data/private/chat/s_' . md5($Configuration['APPLICATION_PATH']);
	$Configuration['PfcLog']   = $Configuration['PfcPath'] . 'data/private/logs/' . md5($Configuration['APPLICATION_PATH']) . '/chat.log';

	function SetList_Init_PFC(&$SetList)
	{
		$elements = &$SetList->DelegateParameters['Form']['elements'];
		$logsize = file_exists($SetList->Context->Configuration['PfcLog']) ?
			(integer)(filesize($SetList->Context->Configuration['PfcLog']) / 1024) : 0;
		$elements['DeleteLogFile']['description'] =
			str_replace('//1', $logsize, $elements['DeleteLogFile']['description']);

		// Look in the i18n directory for translation files.
		$languages = array();
		$i18n = $SetList->Context->Configuration['PfcPath'] . 'i18n/';
		if ( is_dir($i18n) ) {
			$dir = opendir($i18n);
			while ( false !== ($item = readdir($dir)) ) {
				// If the translation file can't be opened, carry on.
				if ( !file_exists($i18n . $item . '/main.php') ) {
					continue;
				}
				$languages[$item] = '';

				// Scan the file for a translation name.
				foreach ( file($i18n . $item . '/main.php') as $line ) {
					$star = strpos($line, '*');
					$trans = strpos($line, ' translation');
					if ( (false !== $star) && (false !== $trans) ) {
						$languages[$item] = trim(substr($line, $star+1, $trans-$star));
						break;
					}
				}
			}
		}

		// Add languages to the select box.
		ksort($languages);
		foreach ( $languages as $key => $val ) {
			$elements['Language']['options'][$key]['label'] = $key . ($val ? (' - ' . $val) : '');
			$elements['Language']['options'][$key]['value'] = $key;
		}

		// Look for themes.
		$themelist = array();
		$themes = $SetList->Context->Configuration['PfcPath'] . 'themes/';
		if ( is_dir($themes) ) {
			$dir = opendir($themes);
			while ( false !== ($item = readdir($dir)) ) {
				if ( is_dir($themes . $item) && (substr($item, 0, 1) != '.') ) {
					$elements['Theme']['options'][$item]['label'] = $item;
					$elements['Theme']['options'][$item]['value'] = $item;
				}
			}
		}
		ksort($elements['Theme']['options']);
	}
	$Context->AddToDelegate('SetList', 'Init_PFC', 'SetList_Init_PFC');

	// It's intensely annoying to have to write this function, but PHP in
	// its infinite wisdom does not have any way to remove a directory and
	// all of its contents, making it necessary to re-invent the wheel here.
	function SetList_Rmdir($filepath)
	{
		if ( is_dir($filepath) && !is_link($filepath) ) {
			if ( $dir = opendir($filepath) ) {
				while ( false !== ($file = readdir($dir)) ) {
					if ( ('.' != $file) && ('..' != $file) ) {
						SetList_Rmdir($filepath . DIRECTORY_SEPARATOR . $file);
					}
				}
				closedir($dir);
			}
			return rmdir($filepath);
		}
		return unlink($filepath);
	}

	function SetList_Process_PFC(&$SetList)
	{
		$elements = &$SetList->DelegateParameters['Form']['elements'];

		// Force some values to integers.
		$elements['Height']['value'] = ForceInt($elements['Height']['value'], 230);
		$elements['FloodDelay']['value'] = ForceInt($elements['FloodDelay']['value'], 5);
		$elements['FloodMessages']['value'] = ForceInt($elements['FloodMessages']['value'], 10);
		$elements['FloodCharacters']['value'] = ForceInt($elements['FloodCharacters']['value'], 450);

		// Take no further action if there were errors.
		if ( $SetList->Context->WarningCollector->Iif() ) {

			// Just to be sure, delete the cache any time settings are saved.
			if ( file_exists($SetList->Context->Configuration['PfcCache']) ) {
				unlink($SetList->Context->Configuration['PfcCache']);
			}
			if ( file_exists($SetList->Context->Configuration['PfcChat']) ) {
				SetList_Rmdir($SetList->Context->Configuration['PfcChat']);
			}

			// Delete the log file if the user requests it.
			if ( $elements['DeleteLogFile']['value'] ) {
				if ( file_exists($SetList->Context->Configuration['PfcLog']) ) {
					unlink($SetList->Context->Configuration['PfcLog']);
				}
				$elements['DeleteLogFile']['value'] = 0;
				$elements['DeleteLogFile']['description'] =
					$SetList->Context->GetDefinition('PFC.LogDeleted');
			}
		}
	}
	$Context->AddToDelegate('SetList', 'Process_PFC', 'SetList_Process_PFC');

	return;
}


// Add the chatbox to extension.php
if ( ('extension.php' == $Context->SelfUrl) && (ForceIncomingString('PostBackAction', '') == 'PFC') ) {

	if ( !@include($Configuration['PfcPath'] . 'src/phpfreechat.class.php') ) {
		$Context->WarningCollector->Add($Context->GetDefinition('PFC.ErrLoadFailed'));
	}

	class PfcChatControl extends Control
	{
		var $pfc;

		function PfcChatControl(&$Context)
		{
			// Call the base class constructor.
			$this->Control($Context);

			$params = array();
			$params['serverid']    = md5($Context->Configuration['APPLICATION_PATH']);
			$params['title']       = $Context->Configuration['APPLICATION_TITLE'] . ' - ' . $Context->Configuration['PfcPageTitle'];
			$params['height']      = ForceInt(@$Context->Configuration['PfcHeight'], 230);
			$params['height']      = ($params['height'] > 0) ? ($params['height'] . 'px') : ('230px');
			$params['frozen_nick'] = true;
			$params['nick']        = ($Context->Session->UserID != 0) ? $Context->Session->User->Name : ($Context->Session->User->Role . rand(1000,9999));
			$params['admins']      = array( ($Context->Session->User->Permission('PERMISSION_CHAT_ADMIN') ? $params['nick'] : ($params['nick']).'1') => '' );
			$params['theme_default_url']  = $Context->Configuration['PfcUrl'] . 'themes';
			$params['theme_url']          = $Context->Configuration['PfcUrl'] . 'themes';
			$params['server_script_url']  = GetUrl($Context->Configuration, 'extension.php', '', 'PostBackAction', 'PFC');
			$params['data_public_url']    = $Context->Configuration['PfcUrl'] . 'data/public';
			$params['prototypejs_url']    = $Context->Configuration['PfcUrl'] . 'data/public/js/prototype.js';
			$params['client_script_path'] = $Context->Configuration['APPLICATION_PATH'] . 'extension.php';
			$params['server_script_path'] = $Context->Configuration['APPLICATION_PATH'] . 'extension.php';
			$params['skip_proxies']       = array();

			// Set censor control.
			if ( @$Context->Configuration['PfcSkipCensor'] ) {
				$params['skip_proxies'][] = 'censor';
			}
			else {
				if ( !isset($Context->Configuration['PfcCensorWords']) ) {
					$Context->Configuration['PfcCensorWords'] = 'fuck,sex,bitch';
				}
				$params['proxies_cfg']['censor']['words'] = 
					array_map('trim', explode(',', $Context->Configuration['PfcCensorWords']));
			}

			// Set flood control.
			if ( @$Context->Configuration['PfcSkipFlood'] ) {
				$params['skip_proxies'][] = 'noflood';
			}
			else {
				$params['proxies_cfg']['noflood']['charlimit'] = ForceInt(@$Context->Configuration['PfcFloodCharacters'], 450);
				$params['proxies_cfg']['noflood']['msglimit']  = ForceInt(@$Context->Configuration['PfcFloodMessages'], 10);
				$params['proxies_cfg']['noflood']['delay']     = ForceInt(@$Context->Configuration['PfcFloodDelay'], 5);
			}

			// Set log control.
			if ( @$Context->Configuration['PfcSkipLog'] ) {
				$params['skip_proxies'][] = 'log';
			}

			// Set chat box language.
			if ( @$Context->Configuration['PfcLanguage'] ) {
				$params['language'] = $Context->Configuration['PfcLanguage'];
			}

			// Set chat box theme.
			if ( @$Context->Configuration['PfcTheme'] ) {
				$params['theme'] = $Context->Configuration['PfcTheme'];
			}

			// Initialize chat channels.
			$params['channels'] = array();
			$channels = array_map('trim', explode(',', @$Context->Configuration['PfcChannels']));
			if ( empty($channels) ) {
				$channels[] = 'Main Lobby';
			}
			foreach ($channels as $c) {
				if ($c) $params['channels'][] = $c;
			}

			if ( !$Context->Session->User->Permission('PERMISSION_USE_CHAT') ) {
				$Context->WarningCollector->Add($Context->GetDefinition('PFC.ErrPermission'));
			}

			if ( $Context->WarningCollector->Iif() ) {
				$this->pfc = new phpFreeChat($params);
			}
		}

		function Render()
		{
			if ( $this->Context->WarningCollector->Iif() ) {
				$this->pfc->printChat();
			}
			else {
				$this->Render_Warnings();
			}
		}
	}

	$Context->PageTitle = $Configuration['PfcPageTitle'];
	if ( @$Configuration['PfcNotice'] ) {
		$NoticeCollector->AddNotice($Configuration['PfcNotice']);
	}

	$Chat = $Context->ObjectFactory->CreateControl($Context, 'PfcChatControl');
	$Page->AddRenderControl($Chat, $Configuration['CONTROL_POSITION_BODY_ITEM']);
}

if ( !@$Configuration['PfcHidePanelLink'] && isset($Panel) && $Context->Session->User->Permission('PERMISSION_USE_CHAT') ) {
	$Panel->AddString('<h1><a href="'.GetUrl($Configuration, 'extension.php', '', 'PostBackAction', 'PFC').'">' . $Configuration['PfcPageTitle'] . '</a></h1>');
}

?>
